package com.hui.platform.falseworkapi.common.security;

import com.hui.platform.falseworkapi.common.security.base.IBasicHttpSecurityConfigurer;
import com.hui.platform.falseworkapi.common.security.constant.SecurityConstant;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author hui
 */
@Order(1)
@Configuration
@EnableWebSecurity
@ConditionalOnWebApplication
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        Map<String, IBasicHttpSecurityConfigurer> configurers = getApplicationContext().getBeansOfType(IBasicHttpSecurityConfigurer.class);
        //根据Order进行排序
        List<IBasicHttpSecurityConfigurer> orderList = configurers.values().stream()
                .sorted(Comparator.comparingInt(IBasicHttpSecurityConfigurer::order)).collect(Collectors.toList());
        for (IBasicHttpSecurityConfigurer t : orderList) {
            t.configure(http);
        }
        //其他请求全部认证及表单登录 这里需要最后配置
        http.authorizeRequests().anyRequest().authenticated();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .passwordEncoder(new BCryptPasswordEncoder())
            .withUser("admin").password(new BCryptPasswordEncoder().encode("admin")).roles(SecurityConstant.SYSTEM_DEV);
    }

    /**
     * 密码编码器--自定义编码器，先进行前端加密--解密字符串，再进行加密
     *
     * @return 编码器
     */
    @Bean
    public PasswordEncoder passwordEncoder() {

        //默认先采用BCryptPasswordEncoder进行加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

        return new PasswordEncoder() {
            /**
             * 对密码进行加密
             * @param rawPassword 前端传送过来的密码
             * @return 加密后的密码
             */
            @Override
            public String encode(CharSequence rawPassword) {
                return bCryptPasswordEncoder.encode(rawPassword);
            }

            /**
             *  密码匹配（先进行前端加密--解密字符串，再进行加密）
             * @param rawPassword 前端传送过来的密码
             * @param encodedPassword 加密后的密码
             * @return 是否匹配正确
             */
            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return bCryptPasswordEncoder.matches(rawPassword,encodedPassword);
            }
        };
    }

}
